﻿using System;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Sovacode.RubiksCube.Common.Base;
using Sovacode.RubiksCube.Common.Exceptions;
using Sovacode.RubiksCube.Common.ViewModel;

namespace Sovacode.RubiksCube.Common.Tests.ViewModelCommon
{
    [TestClass]
    public class ExpressionHelperTests
    {
        [TestMethod]
        public void ExtractName()
        {
            var viewModel = new ViewModelTop();

            Expression<Func<bool>> exprProperty = () => viewModel.IsValid;

            Assert.IsFalse(string.IsNullOrWhiteSpace(exprProperty.ExtractName()));
            Assert.IsTrue(string.CompareOrdinal(exprProperty.ExtractName(), "IsValid") == 0);

            Expression<Action> exprMethod = () => viewModel.CommandManager.Clear();

            Assert.IsFalse(string.IsNullOrWhiteSpace(exprMethod.ExtractName()));
            Assert.IsTrue(string.CompareOrdinal(exprMethod.ExtractName(), "Clear") == 0);
        }

        [TestMethod]
        public void ExtractNames()
        {
            var viewModel = new ViewModelTop();

            Expression<Func<int>> exprPropTotVal = () => viewModel.ValidatorsCount;
            Expression<Func<int>> exprPropTotSet = () => viewModel.SettingsCount;
            Expression<Func<int>> exprPropTotCom = () => viewModel.CommandsCount;

            var properties = ExpressionHelper.ExpressionToString(exprPropTotVal, exprPropTotSet, exprPropTotCom).ToList();

            Assert.IsNotNull(properties);

            Assert.IsTrue(properties.Count == 3);

            Assert.IsTrue(properties.Contains("ValidatorsCount"));
            Assert.IsTrue(properties.Contains("SettingsCount"));
            Assert.IsTrue(properties.Contains("CommandsCount"));
        }

        [TestMethod]
        [ExpectedException(typeof(ExpressionNullException))]
        public void ExpressionNullFunc()
        {
            Expression<Func<bool>> exprProperty = null;

            ExpressionHelper.ExpressionToString(exprProperty);
        }

        [TestMethod]
        [ExpectedException(typeof(ExpressionNullException))]
        public void ExpressionNullAction()
        {
            Expression<Action> exprMethod = null;

            ExpressionHelper.ExpressionToString(exprMethod);
        }
    }
}
